package com.paradogs.framework.core.annoations.request;

import com.paradogs.framework.core.annoations.base.BaseImportSelector;
import com.paradogs.framework.core.annoations.base.BaseScanner;
import com.paradogs.framework.core.msg.PRMsg;
import com.paradogs.framework.core.msg.route.MsgMapping;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: yumi
 * @date: 2023/8/25  16:15
 * @Description: TODO
 */
@Slf4j
public class PRRequestInterfaceSelector extends BaseImportSelector {

    @Override
    public BaseScanner getScanner(BeanFactory beanFactory) {
        return new PRRequestScanner((DefaultListableBeanFactory) beanFactory);
    }

    @Override
    public void handle(BeanDefinition beanDefinition) {

        try {
            Class<?> beanClass = Class.forName(beanDefinition.getBeanClassName());

            // 扫描方法
            Method[] methods = beanClass.getDeclaredMethods();
            for (Method method : methods) {

                // 计算路由
                PRMsgMapping parentRouteMapping = AnnotationUtils.findAnnotation(method.getDeclaringClass(), PRMsgMapping.class);
                PRMsgMapping msgMapping = AnnotationUtils.findAnnotation(method, PRMsgMapping.class);
                if (msgMapping == null) {
                    continue;
                }
                String route = (parentRouteMapping != null ? (parentRouteMapping.value() + ".") : "") + msgMapping.value();
                if (PRMsgMappingHolder.containsRoute(route)) {
                    throw new RuntimeException("Duplicate route found: " + route);
                }

                // 保存 Msg 类型和要执行的方法
                Class<?> targetMsgClass = null;
                for (Parameter parameter : method.getParameters()) {
                    if (parameter.getAnnotation(com.paradogs.framework.core.annoations.request.PRMsg.class) != null) {
                        targetMsgClass = parameter.getType();

                    } else {
                        // 如果找不到 @PRMsg 修饰，默认第一个参数为消息
                        if (method.getParameters().length > 0) {
                            targetMsgClass = parameter.getType();
                        }
//                        // 如果只有一个 BaseMsg 参数，自动优化添加，等于加了 PdgMsg
//                        List<Parameter> baseMsgList = Stream.of(method.getParameters()).
//                                filter(param -> PRMsg.class.isAssignableFrom(param.getType()))
//                                .collect(Collectors.toList());
//                        if (baseMsgList.size() == 1) {
//                            targetMsgClass = (Class<? extends PRMsg>) parameter.getType();
//                        }

                    }
                }
                PRMsgMappingHolder.put(route, new MsgMapping(targetMsgClass, method, msgMapping.async()));
                log.debug("Register RequestMapping: [{}]", route);
            }

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

    }

}
